package com.yanqu.road.server.manager.activity.hsisland;

import com.yanqu.road.entity.activity.hsisland.config.HsIslandConfig;
import com.yanqu.road.entity.activity.hsisland.data.HsIslandEventData;
import com.yanqu.road.entity.activity.hsisland.data.HsIslandMonsterData;
import com.yanqu.road.entity.activity.hsisland.data.HsIslandReBloodData;
import com.yanqu.road.entity.activity.hsisland.enums.HsIslandBattleFieldEnemyEnum;
import com.yanqu.road.pb.activity.HsIslandProto;
import com.yanqu.road.server.manager.activity.hsisland.pb.CrossHsIslandActivityPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.utils.RandomHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.util.ConcurrentHashSet;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

import static com.yanqu.road.entity.activity.hsisland.enums.HsIslandBattleFieldEnemyEnum.ENEMY_NONE;
import static com.yanqu.road.server.logic.MessageHelper.sendPacket;
import static com.yanqu.road.server.logic.MessageHelper.sendPacketToAll;

/**
 * 海神岛战场
 */
public class CrossHsIslandBattleField {

    /**
     * logger
     */
    private static Logger logger = LogManager.getLogger(CrossHsIslandBattleField.class.getName());

    /**
     * 商会锁
     */
    private ReentrantLock lock = new ReentrantLock();

    private int activityId;

    private int groupId;

    /**
     * 战场Id
     */
    private long battleFieldId;

    /**
     * 敌人类型
     */
    private HsIslandBattleFieldEnemyEnum enemyType = ENEMY_NONE;

    /**
     * 敌人信息
     */
    HsIslandMonsterData monsterData = null;

    /**
     * 事件对象（pve）
     */
    private HsIslandEventData eventData = null;

    /**
     * 战场内玩家信息
     */
    private Map<Long, CrossHsIslandUser> battleUserMap = new ConcurrentHashMap<>();

    /**
     * 待同步的用户信息
     */
    private Set<Long> syncEnterUserIdSet = new ConcurrentHashSet<>();

    /**
     * 待同步的用户信息
     */
    private Set<Long> syncLeaveUserIdSet = new ConcurrentHashSet<>();


    /**
     * 待同步的攻击消息（怪物）
     */
    private List<HsIslandProto.HsIslandBattleFiledAttackResultMsg> attackMonsterResultMsgList = new ArrayList<>();

    /**
     * 待同步的攻击消息(玩家)
     */
    private List<HsIslandProto.HsIslandBattleFiledAttackResultMsg> attackPlayerResultMsgList = new ArrayList<>();




    private RandomHelper randomHelper = new RandomHelper();

    public Set<Long> getSyncEnterUserIdSet() {
        return syncEnterUserIdSet;
    }

    public Set<Long> getSyncLeaveUserIdSet() {
        return syncLeaveUserIdSet;
    }

    /**
     * 获取配置
     *
     * @return
     */
    public HsIslandConfig getConfig() {
        return CrossHsIslandActivityMgr.getConfig(this.activityId, this.groupId);
    }

    /**
     * 获取活动
     * @return
     */
    public CrossHsIslandActivity getActivity() {
        return CrossHsIslandActivityMgr.getActivity(this.activityId, this.groupId);
    }

    public CrossHsIslandBattleField(long battleFieldId) {
        this.battleFieldId = battleFieldId;
    }

    public CrossHsIslandBattleField(int activityId, int groupId, long battleFieldId, HsIslandBattleFieldEnemyEnum enemyType, HsIslandMonsterData monsterData) {
        this.activityId = activityId;
        this.groupId = groupId;
        this.battleFieldId = battleFieldId;
        this.enemyType = enemyType;
        this.monsterData = monsterData;
    }

    public HsIslandEventData getEventData() {
        return eventData;
    }

    public void setEventData(HsIslandEventData eventData) {
        this.eventData = eventData;
    }

    public ReentrantLock getLock() {
        return lock;
    }

    public long getBattleFieldId() {
        return battleFieldId;
    }

    public HsIslandBattleFieldEnemyEnum getEnemyType() {
        return enemyType;
    }

    public HsIslandMonsterData getMonsterData() {
        return monsterData;
    }

    /**
     * 进入战场
     */
    public void enterBattleField(CrossHsIslandUser user) {
        if (user == null || user.getUserData() == null) {
            return;
        }
        long userId = user.getUserData().getUserId();
        // 战场还有人就需要同步
        if (!battleUserMap.isEmpty()) {
            syncEnterUserIdSet.add(userId);
        }

        battleUserMap.put(userId, user);
        // 用户身上也处理下
        user.enterBattleField(getBattleFieldId());

        // 进入战场回包
        HsIslandProto.HsIslandEnterBattleFieldRespMsg.Builder respMsg = HsIslandProto.HsIslandEnterBattleFieldRespMsg.newBuilder();
        respMsg.setRet(0);
        // 战场信息
        respMsg.setBattleField(CrossHsIslandActivityPb.builderHsIslandBattleFieldData(this));
        // 我的个人信息
        respMsg.setMyUserData(CrossHsIslandActivityPb.buildHsIslandBattleFieldUserData(this, user));
        // 我的商会信息
        respMsg.setMyUnionData(CrossHsIslandActivityPb.buildHsIslandBattleFieldUnionData(this, user));
        sendPacket(ClientProtocol.U_HS_ISLAND_ENTER_BATTLE_FIELD, respMsg, userId);
    }

    /**
     * 离开战场
     */
    public void leaveBattleField(CrossHsIslandUser user) {
        if (user == null || user.getUserData() == null) {
            return;
        }
        long userId = user.getUserData().getUserId();
        battleUserMap.remove(userId);
        // 用户身上的也处理下
        user.leaveBattleField();

        // 战场还有人就需要同步
        if (!battleUserMap.isEmpty()) {
            syncLeaveUserIdSet.add(userId);
        }

        // 离开战场回包
        HsIslandProto.HsIslandLeaveBattleFieldRespMsg.Builder respMsg = HsIslandProto.HsIslandLeaveBattleFieldRespMsg.newBuilder();
        respMsg.setRet(0);
        sendPacket(ClientProtocol.U_HS_ISLAND_LEAVE_BATTLE_FIELD, respMsg, userId);
    }

    /**
     * 进入战场同步任务
     */
    public void syncEnterBattleField() {
        if (syncEnterUserIdSet.isEmpty()) {
            return;
        }
        ConcurrentHashSet<Long> syncList = new ConcurrentHashSet<>(syncEnterUserIdSet);
        syncEnterUserIdSet.clear();

        // 同步消息
        HsIslandProto.HsIslandEnterBattleFieldSyncMsg.Builder syncMsg = HsIslandProto.HsIslandEnterBattleFieldSyncMsg.newBuilder();
        for (Long userId : syncList) {
            CrossHsIslandUser battleUser = getBattleUser(userId);
            if (battleUser == null) {
                continue;
            }
            syncMsg.addUserData(CrossHsIslandActivityPb.buildHsIslandBattleFieldUserData(this, battleUser));
        }
        // 同步给战场里的所有人
        if (!syncMsg.getUserDataList().isEmpty()) {
            sendPacketToAll(ClientProtocol.U_HS_ISLAND_SYNC_ENTER_BATTLE_FIELD, syncMsg, this.battleUserMap.keySet());
        }
    }

    public CrossHsIslandUser getBattleUser(long userId) {
        return battleUserMap.get(userId);
    }

    /**
     * 离开战场同步任务
     */
    public void syncLeaveBattleField() {
        if (syncLeaveUserIdSet.isEmpty()) {
            return;
        }
        ConcurrentHashSet<Long> syncList = new ConcurrentHashSet<>(syncLeaveUserIdSet);
        syncLeaveUserIdSet.clear();

        // 同步消息
        HsIslandProto.HsIslandLeaveBattleFieldSyncMsg.Builder syncMsg = HsIslandProto.HsIslandLeaveBattleFieldSyncMsg.newBuilder();
        syncMsg.addAllUserIdList(syncList);
        // 同步给战场里的所有人
        if (!syncMsg.getUserIdListList().isEmpty()) {
            sendPacketToAll(ClientProtocol.U_HS_ISLAND_SYNC_LEAVE_BATTLE_FIELD, syncMsg, this.battleUserMap.keySet());
        }
    }

    /**
     * 随机获取战场内的一个敌人
     */
    public long getRandomEnemyUserId(CrossHsIslandUser user) {
        // 随机攻击房间内的敌人
        List<Long> enemyList = new ArrayList<>();
        for (CrossHsIslandUser enemy : this.getBattleUserMap().values()) {
            // 自己不能打
            if (enemy.getUserData().getUserId() == user.getUserData().getUserId()) {
                continue;
            }
            // 同商会不打
            if (enemy.getUserData().getUnionId().equals(user.getUserData().getUnionId())) {
                continue;
            }
            // 调息状态不能打
            if (enemy.isPvpRest()) {
                continue;
            }
            // 魂力限制不能打
            if (!user.checkAttackPlayerPowerLimit(enemy.getPower())) {
                continue;
            }
            enemyList.add(enemy.getUserData().getUserId());
        }
        if (enemyList.isEmpty()) {
            return 0;
        }
        return enemyList.get(randomHelper.next(0, enemyList.size()));
    }

    public Map<Long, CrossHsIslandUser> getBattleUserMap() {
        return battleUserMap;
    }

    public int getActivityId() {
        return activityId;
    }

    public int getGroupId() {
        return groupId;
    }

    /**
     * 添加攻击同步
     * @param attackResultMsg
     */
    public void addAttackMonsterResultMsg(HsIslandProto.HsIslandBattleFiledAttackResultMsg attackResultMsg) {
        synchronized (attackMonsterResultMsgList) {
            if (attackMonsterResultMsgList.size() >= 50) {
                attackMonsterResultMsgList.remove(0);
            }
            attackMonsterResultMsgList.add(attackResultMsg);
        }
    }

    /**
     * 添加攻击同步
     * @param attackResultMsg
     */
    public void addAttackPlayerResultMsg(HsIslandProto.HsIslandBattleFiledAttackResultMsg attackResultMsg) {
        synchronized (attackPlayerResultMsgList) {
            attackPlayerResultMsgList.add(attackResultMsg);
        }
    }

    /**
     * 战场攻击同步
     */
    public void syncBattleFieldAttack() {
        if (attackPlayerResultMsgList.isEmpty() && attackMonsterResultMsgList.isEmpty()) {
            return;
        }
        List<HsIslandProto.HsIslandBattleFiledAttackResultMsg> tmpAttackResultMsgList = new ArrayList<>();
        synchronized (attackPlayerResultMsgList) {
            if (!attackPlayerResultMsgList.isEmpty()) {
                tmpAttackResultMsgList.addAll(new ArrayList<>(attackPlayerResultMsgList));
                attackPlayerResultMsgList.clear();
            }
        }
        synchronized (attackMonsterResultMsgList) {
            if (!attackMonsterResultMsgList.isEmpty()) {
                tmpAttackResultMsgList.addAll(new ArrayList<>(attackMonsterResultMsgList));
                attackMonsterResultMsgList.clear();
            }
        }
        if (!tmpAttackResultMsgList.isEmpty()) {
            HsIslandProto.HsIslandBattleFieldAttackSyncMsg.Builder syncMsg = HsIslandProto.HsIslandBattleFieldAttackSyncMsg.newBuilder();
            syncMsg.addAllAttackResult(tmpAttackResultMsgList);
            sendPacketToAll(ClientProtocol.U_HS_ISLAND_SYNC_ATTACK_BATTLE_FIELD, syncMsg, this.battleUserMap.keySet());
        }
    }
}
